using System;
using System.Collections;
using System.Collections.Generic;
using BitMango.Diagnostics;
using Data;
using Holoville.HOTween;
using SevenPieceGame;
using UnityEngine;

public class PuzzleCtrl : MonoBehaviour
{
	public List<BoardInfo> BoardInfos
	{
		get
		{
			return this.boardInfos;
		}
	}

	public int MoveCount
	{
		get
		{
			return this.moveCount;
		}
	}

	public int GetMinMoves
	{
		get
		{
			return this.boxInitRootWidgets.Count;
		}
	}

	private void OnEnable()
	{
		InputManager.onMouseDown = (Action<Vector3>)Delegate.Combine(InputManager.onMouseDown, new Action<Vector3>(this.OnMouseDown));
		InputManager.onMouseDrag = (Action<Vector3>)Delegate.Combine(InputManager.onMouseDrag, new Action<Vector3>(this.OnMouseDrag));
		InputManager.onMouseUp = (Action<Vector3>)Delegate.Combine(InputManager.onMouseUp, new Action<Vector3>(this.OnMouseUp));
	}

	private void OnDisable()
	{
		InputManager.onMouseDown = (Action<Vector3>)Delegate.Remove(InputManager.onMouseDown, new Action<Vector3>(this.OnMouseDown));
		InputManager.onMouseDrag = (Action<Vector3>)Delegate.Remove(InputManager.onMouseDrag, new Action<Vector3>(this.OnMouseDrag));
		InputManager.onMouseUp = (Action<Vector3>)Delegate.Remove(InputManager.onMouseUp, new Action<Vector3>(this.OnMouseUp));
	}

	public void LoadLevel(Level _level, bool _isTutorial, bool _isReply = false)
	{
		Debugger.Assert(_level != null, "PuzzleCtrl _level != null");
		this.isTutorial = _isTutorial;
		this.RemoveBoard();
		MainManager.Instance.m_CurTempPieceCount = _level.blockcount;
		if (!_isReply)
		{
			this.moveCount = 0;
			this.currentlevel = _level;
		}
		for (int i = 0; i < 3; i++)
		{
			BlocksCoordinate.coordinate.initCoordinate.width = BlocksCoordinate.coordinate.vaildInitCoordinates[i].width;
			BlocksCoordinate.coordinate.initCoordinate.height = BlocksCoordinate.coordinate.vaildInitCoordinates[i].height;
			BlocksCoordinate.coordinate.initCoordinate.size = BlocksCoordinate.coordinate.vaildInitCoordinates[i].size;
			if (this.IsVaildInitPosition())
			{
				break;
			}
		}
		this.topY = this.topPosition.transform.position.y - BlocksCoordinate.coordinate.initCoordinate.SizeY / 2f;
		this.bottomY = this.bottomPosition.transform.position.y + BlocksCoordinate.coordinate.initCoordinate.SizeY / 2f;
		this.GenerateBoard();
		this.GenerateHinder();
		if (!_isReply)
		{
			this.GeneratePosition();
		}
		this.GenerateBlock(_isReply);
		this.GenerateInitBoard();
		this.GeneratePixBlock();
		this.SetColorBlock(true);
		if (this.isTutorial)
		{
			this.StartTutorial();
		}
	}

	private bool IsVaildInitPosition()
	{
		List<BoardInfo> list = new List<BoardInfo>();
		for (int i = 0; i < BlocksCoordinate.coordinate.initCoordinate.width; i++)
		{
			for (int j = 0; j < BlocksCoordinate.coordinate.initCoordinate.height; j++)
			{
				BoardInfo boardInfo = new BoardInfo();
				boardInfo.point = new Point(i, j);
				boardInfo.index = -1;
				bool isUp = (i + j) % 2 == 0;
				boardInfo.isUp = isUp;
				list.Add(boardInfo);
			}
		}
		for (int k = 0; k < this.currentlevel.index.Length; k++)
		{
			int num = (int)this.currentlevel.index[k];
			this.vaildInitPosition.SetData(this.currentlevel.level[num], num, this.currentlevel.isReverse);
			Point currentRootPoint = this.vaildInitPosition.PixBlockPosition(list);
			if (currentRootPoint.x == -100)
			{
				return false;
			}
			this.vaildInitPosition.SetInitValidPosition(list, currentRootPoint, true);
		}
		return true;
	}

	private void GenerateBoard()
	{
		this.boardInfos.Clear();
		int num = 0;
		for (int i = 0; i < this.currentlevel.blockcount; i++)
		{
			for (int j = 0; j < this.currentlevel.level[i].Length; j++)
			{
				Point point = BlocksCoordinate.coordinate.coordinate.IndexToPuzzle((int)this.currentlevel.level[i][j]);
				bool isUp;
				if (this.currentlevel.isReverse)
				{
					isUp = ((point.x + point.y) % 2 != 0);
				}
				else
				{
					isUp = ((point.x + point.y) % 2 == 0);
				}
				Vector3 localPosition = BlocksCoordinate.coordinate.coordinate.PuzzleToWorld((float)point.x, (float)point.y);
				localPosition.z = 0f;
				BoardInfo boardInfo = new BoardInfo();
				boardInfo.point = new Point(point);
				boardInfo.index = -1;
				boardInfo.isUp = isUp;
				if (this.currentlevel.changeColor != null)
				{
					boardInfo.changeColorIndex = (int)this.currentlevel.changeColor[i][j];
				}
				boardInfo.tangramIndex = (point.x + (int)this.currentlevel.editMinPoint[0] + (((point.y + (int)this.currentlevel.editMinPoint[1]) % 2 != 0) ? 2 : 0)) % 4;
				this.boardInfos.Add(boardInfo);
				if (this.boardWidgets.Count - 1 < num)
				{
					BoardWidgetHandler item = Widget.Create<BoardWidgetHandler>();
					this.boardWidgets.Add(item);
				}
				this.boardWidgets[num].transform.parent = this.boardBg.transform;
				this.boardWidgets[num].transform.localPosition = localPosition;
				this.boardWidgets[num].transform.localScale = Vector3.one * BlocksCoordinate.coordinate.coordinate.size;
				this.boardWidgets[num].SetData(isUp, point, this.currentlevel.editMinPoint, -1, false);
				this.boardWidgets[num].name = "board";
				num++;
			}
		}
		if (this.currentlevel.hinder != null)
		{
			for (int k = 0; k < this.currentlevel.hinder.Length; k++)
			{
				Point point2 = BlocksCoordinate.coordinate.coordinate.IndexToPuzzle((int)this.currentlevel.hinder[k]);
				bool isUp2;
				if (this.currentlevel.isReverse)
				{
					isUp2 = ((point2.x + point2.y) % 2 != 0);
				}
				else
				{
					isUp2 = ((point2.x + point2.y) % 2 == 0);
				}
				Vector3 localPosition2 = BlocksCoordinate.coordinate.coordinate.PuzzleToWorld((float)point2.x, (float)point2.y);
				localPosition2.z = 0f;
				if (this.boardWidgets.Count - 1 < num)
				{
					BoardWidgetHandler item2 = Widget.Create<BoardWidgetHandler>();
					this.boardWidgets.Add(item2);
				}
				this.boardWidgets[num].transform.parent = this.boardBg.transform;
				this.boardWidgets[num].transform.localPosition = localPosition2;
				this.boardWidgets[num].transform.localScale = Vector3.one * BlocksCoordinate.coordinate.coordinate.size;
				this.boardWidgets[num].SetData(isUp2, point2, this.currentlevel.editMinPoint, -1, false);
				this.boardWidgets[num].name = "board";
				num++;
			}
		}
	}

	private void GenerateInitBoard()
	{
		this.initInfos.Clear();
		for (int i = 0; i < BlocksCoordinate.coordinate.initCoordinate.width; i++)
		{
			for (int j = 0; j < BlocksCoordinate.coordinate.initCoordinate.height; j++)
			{
				BoardInfo boardInfo = new BoardInfo();
				boardInfo.point = new Point(i, j);
				boardInfo.index = -1;
				bool isUp = (i + j) % 2 == 0;
				boardInfo.isUp = isUp;
				this.initInfos.Add(boardInfo);
			}
		}
	}

	private void GenerateHinder()
	{
		int num = 0;
		if (this.currentlevel.hinder != null)
		{
			for (int i = 0; i < this.currentlevel.hinder.Length; i++)
			{
				Point point = BlocksCoordinate.coordinate.coordinate.IndexToPuzzle((int)this.currentlevel.hinder[i]);
				bool isUp;
				if (this.currentlevel.isReverse)
				{
					isUp = ((point.x + point.y) % 2 != 0);
				}
				else
				{
					isUp = ((point.x + point.y) % 2 == 0);
				}
				int tangramIndex = (point.x + (int)this.currentlevel.editMinPoint[0] + (((point.y + (int)this.currentlevel.editMinPoint[1]) % 2 != 0) ? 2 : 0)) % 4;
				Vector3 localPosition = BlocksCoordinate.coordinate.coordinate.PuzzleToWorld((float)point.x, (float)point.y);
				localPosition.z = -2f;
				if (this.hinderWidgets.Count - 1 < num)
				{
					HinderWidgetHandler item = Widget.Create<HinderWidgetHandler>();
					this.hinderWidgets.Add(item);
				}
				this.hinderWidgets[num].transform.parent = this.boardBg.transform;
				this.hinderWidgets[num].transform.localPosition = localPosition;
				this.hinderWidgets[num].transform.localScale = Vector3.one * BlocksCoordinate.coordinate.coordinate.size;
				this.hinderWidgets[num].name = "hinder";
				this.hinderWidgets[num].SetData(isUp, tangramIndex);
				num++;
			}
		}
	}

	private void GeneratePosition()
	{
		float num = 9999f;
		float num2 = -9999f;
		for (int i = 0; i < this.boardWidgets.Count; i++)
		{
			if (this.boardWidgets[i].transform.position.y < num)
			{
				num = this.boardWidgets[i].transform.position.y;
			}
			if (this.boardWidgets[i].transform.position.y > num2)
			{
				num2 = this.boardWidgets[i].transform.position.y;
			}
		}
		for (int j = 0; j < this.hinderWidgets.Count; j++)
		{
			if (this.hinderWidgets[j].transform.position.y < num)
			{
				num = this.hinderWidgets[j].transform.position.y;
			}
			if (this.hinderWidgets[j].transform.position.y > num2)
			{
				num2 = this.hinderWidgets[j].transform.position.y;
			}
		}
		Vector3 position = base.transform.position;
		float num3 = (num - position.y + (num2 - position.y)) / 2f;
		base.transform.localPosition = new Vector3(base.transform.localPosition.x, base.transform.localPosition.y - num3, base.transform.localPosition.z);
	}

	private void GenerateBlock(bool isReply)
	{
		this.ClearBoxRootWidget(0);
		this.ClearBoxHintRootWidget(0);
		this.ClearBoxShadowRootWidget(0);
		this.ClearBoxInitRootWidget(0);
		List<int> list = new List<int>();
		for (int i = 0; i < this.currentlevel.level.Length; i++)
		{
			list.Add(i);
		}
		List<int> list2 = new List<int>();
		System.Random random = new System.Random(this.currentlevel.num);
		while (list.Count > 0)
		{
			int index = random.Next(0, list.Count);
			list2.Add(list[index]);
			list.RemoveAt(index);
		}
		for (int j = 0; j < this.currentlevel.level.Length; j++)
		{
			Point point = BlocksCoordinate.coordinate.coordinate.IndexToPuzzle((int)this.currentlevel.level[j][0]);
			Vector3 localPosition = BlocksCoordinate.coordinate.coordinate.PuzzleToWorld((float)point.x, (float)point.y);
			localPosition.z = -2f;
			if (this.boxRootWidgets.Count - 1 < j)
			{
				BoxRootWidgetHandler item = Widget.Create<BoxRootWidgetHandler>();
				this.boxRootWidgets.Add(item);
				BoxRootWidgetHandler item2 = Widget.Create<BoxRootWidgetHandler>();
				this.boxShadowRootWidgets.Add(item2);
				BoxRootWidgetHandler item3 = Widget.Create<BoxRootWidgetHandler>();
				this.boxInitRootWidgets.Add(item3);
			}
			this.boxRootWidgets[j].transform.parent = base.transform;
			this.boxRootWidgets[j].transform.localPosition = localPosition;
			this.boxRootWidgets[j].name = "boxRoot" + j;
			this.boxRootWidgets[j].transform.localScale = Vector3.one;
			this.boxRootWidgets[j].SetData(base.gameObject, this.currentlevel.level[j], j, list2[j], this.currentlevel.isReverse, this.currentlevel.editMinPoint, BlockType.NORMAL);
			this.boxRootWidgets[j].transform.localScale = Vector3.one * BlocksCoordinate.coordinate.initCoordinate.size / BlocksCoordinate.coordinate.coordinate.size;
			this.boxShadowRootWidgets[j].transform.parent = base.transform;
			this.boxShadowRootWidgets[j].transform.localPosition = localPosition;
			this.boxShadowRootWidgets[j].name = "boxShadowRoot" + j;
			this.boxShadowRootWidgets[j].transform.localScale = Vector3.one;
			this.boxShadowRootWidgets[j].SetData(base.gameObject, this.currentlevel.level[j], j, list2[j], this.currentlevel.isReverse, this.currentlevel.editMinPoint, BlockType.SHADOW);
			this.boxShadowRootWidgets[j].transform.localScale = Vector3.one * BlocksCoordinate.coordinate.initCoordinate.size / BlocksCoordinate.coordinate.coordinate.size;
			this.boxShadowRootWidgets[j].gameObject.SetActive(false);
			this.boxInitRootWidgets[j].transform.parent = base.transform;
			localPosition.z = -3f;
			this.boxInitRootWidgets[j].transform.localPosition = localPosition;
			this.boxInitRootWidgets[j].name = "boxInitRoot" + j;
			this.boxInitRootWidgets[j].transform.localScale = Vector3.one;
			this.boxInitRootWidgets[j].SetData(base.gameObject, this.currentlevel.level[j], j, list2[j], this.currentlevel.isReverse, this.currentlevel.editMinPoint, BlockType.INIT);
			this.boxInitRootWidgets[j].transform.localScale = Vector3.one * BlocksCoordinate.coordinate.initCoordinate.size / BlocksCoordinate.coordinate.coordinate.size;
			if (this.currentlevel.blockcount > j)
			{
				if (!isReply)
				{
					if (this.boxHintRootWidgets.Count - 1 < j)
					{
						BoxRootWidgetHandler item4 = Widget.Create<BoxRootWidgetHandler>();
						this.boxHintRootWidgets.Add(item4);
					}
					localPosition.z = -1f;
					this.boxHintRootWidgets[j].transform.parent = base.transform;
					this.boxHintRootWidgets[j].transform.localPosition = localPosition;
					this.boxHintRootWidgets[j].name = "boxHintRoot" + j;
					this.boxHintRootWidgets[j].transform.localScale = Vector3.one;
					this.boxHintRootWidgets[j].SetData(base.gameObject, this.currentlevel.level[j], j, list2[j], this.currentlevel.isReverse, this.currentlevel.editMinPoint, BlockType.HINT);
					this.boxHintRootWidgets[j].gameObject.SetActive(false);
					if (this.boxHintRootWidgets[j].gameObject.GetComponent<HintAnimation>() == null)
					{
						this.boxHintRootWidgets[j].gameObject.AddComponent<HintAnimation>();
					}
				}
			}
		}
	}

	private void GeneratePixBlock()
	{
		this.initPoint.transform.localPosition = new Vector3(0f, 2.78f, 0f);
		for (int i = 0; i < this.currentlevel.index.Length; i++)
		{
			int index = (int)this.currentlevel.index[i];
			Point currentRootPoint = this.PixBlockPosition(this.boxInitRootWidgets[index]);
			if (currentRootPoint.x != -100)
			{
				this.boxInitRootWidgets[index].SetInitValidPosition(this.initInfos, currentRootPoint, true);
				Vector3 localPosition = BlocksCoordinate.coordinate.initCoordinate.PuzzleToWorld((float)currentRootPoint.x, (float)currentRootPoint.y);
				localPosition.z = -2f;
				this.boxRootWidgets[index].transform.parent = this.initPoint.transform;
				this.boxRootWidgets[index].transform.localPosition = localPosition;
				this.boxShadowRootWidgets[index].transform.parent = this.initPoint.transform;
				this.boxShadowRootWidgets[index].transform.localPosition = localPosition;
				this.boxInitRootWidgets[index].transform.parent = this.initPoint.transform;
				this.boxInitRootWidgets[index].transform.localPosition = localPosition;
			}
		}
		float num = 9999f;
		float num2 = -9999f;
		float num3 = 9999f;
		float num4 = -9999f;
		for (int j = 0; j < this.boxInitRootWidgets.Count; j++)
		{
			for (int k = 0; k < this.boxInitRootWidgets[j].boxWidgets.Count; k++)
			{
				if (this.boxInitRootWidgets[j].boxWidgets[k].transform.position.x < num)
				{
					num = this.boxInitRootWidgets[j].boxWidgets[k].transform.position.x;
				}
				if (this.boxInitRootWidgets[j].boxWidgets[k].transform.position.x > num2)
				{
					num2 = this.boxInitRootWidgets[j].boxWidgets[k].transform.position.x;
				}
				if (this.boxInitRootWidgets[j].boxWidgets[k].transform.position.y < num3)
				{
					num3 = this.boxInitRootWidgets[j].boxWidgets[k].transform.position.y;
				}
				if (this.boxInitRootWidgets[j].boxWidgets[k].transform.position.y > num4)
				{
					num4 = this.boxInitRootWidgets[j].boxWidgets[k].transform.position.y;
				}
			}
		}
		Vector3 position = this.initPoint.transform.position;
		float num5 = (num - position.x + (num2 - position.x)) / 2f;
		float num6 = (num3 - position.y + (num4 - position.y)) / 2f;
		this.initPoint.transform.localPosition = new Vector3(this.initPoint.transform.localPosition.x - num5, this.initPoint.transform.localPosition.y - num6, 0f);
		for (int l = 0; l < this.boxInitRootWidgets.Count; l++)
		{
			this.boxRootWidgets[l].transform.parent = base.transform;
			this.boxShadowRootWidgets[l].transform.parent = base.transform;
			this.boxInitRootWidgets[l].transform.parent = base.transform;
		}
		for (int m = 0; m < this.boxRootWidgets.Count; m++)
		{
			this.boxRootWidgets[m].SetPoints(this.initPoint, false);
			this.boxShadowRootWidgets[m].SetPoints(this.initPoint, false);
			this.boxInitRootWidgets[m].SetPoints(this.initPoint, false);
		}
	}

	private Point PixBlockPosition(BoxRootWidgetHandler widget)
	{
		Debugger.Assert(widget != null, "PuzzleCtrl widget != null");
		for (int i = 0; i < BlocksCoordinate.coordinate.initCoordinate.height; i++)
		{
			for (int j = 0; j < BlocksCoordinate.coordinate.initCoordinate.width; j++)
			{
				if (widget.IsValidPosition(this.initInfos, new Point(j, i), false))
				{
					return new Point(j, i);
				}
			}
		}
		return new Point(-100, -100);
	}

	private void ClearBoardWidget(int index = 0)
	{
		for (int i = index; i < this.boardWidgets.Count; i++)
		{
			UnityEngine.Object.Destroy(this.boardWidgets[i].gameObject);
		}
		this.boardWidgets.RemoveRange(index, this.boardWidgets.Count - index);
	}

	private void ClearInitBoardWidget(int index = 0)
	{
		for (int i = index; i < this.initBoardWidgets.Count; i++)
		{
			UnityEngine.Object.Destroy(this.initBoardWidgets[i].gameObject);
		}
		this.initBoardWidgets.RemoveRange(index, this.initBoardWidgets.Count - index);
	}

	private void ClearHinderWidget(int index = 0)
	{
		for (int i = index; i < this.hinderWidgets.Count; i++)
		{
			UnityEngine.Object.Destroy(this.hinderWidgets[i].gameObject);
		}
		this.hinderWidgets.RemoveRange(index, this.hinderWidgets.Count - index);
	}

	private void ClearBoxRootWidget(int index = 0)
	{
		for (int i = index; i < this.boxRootWidgets.Count; i++)
		{
			if (this.currentRoot == this.boxRootWidgets[i])
			{
				this.currentRoot = null;
			}
			UnityEngine.Object.Destroy(this.boxRootWidgets[i].gameObject);
		}
		this.boxRootWidgets.RemoveRange(index, this.boxRootWidgets.Count - index);
	}

	private void ClearBoxHintRootWidget(int index = 0)
	{
		for (int i = index; i < this.boxHintRootWidgets.Count; i++)
		{
			UnityEngine.Object.Destroy(this.boxHintRootWidgets[i].gameObject);
		}
		this.boxHintRootWidgets.RemoveRange(index, this.boxHintRootWidgets.Count - index);
	}

	private void ClearBoxShadowRootWidget(int index = 0)
	{
		for (int i = index; i < this.boxShadowRootWidgets.Count; i++)
		{
			if (this.currentShadowRoot == this.boxShadowRootWidgets[i])
			{
				this.currentShadowRoot = null;
			}
			UnityEngine.Object.Destroy(this.boxShadowRootWidgets[i].gameObject);
		}
		this.boxShadowRootWidgets.RemoveRange(index, this.boxShadowRootWidgets.Count - index);
	}

	private void ClearBoxInitRootWidget(int index = 0)
	{
		for (int i = index; i < this.boxInitRootWidgets.Count; i++)
		{
			if (this.currentInitRoot == this.boxInitRootWidgets[i])
			{
				this.currentInitRoot = null;
			}
			UnityEngine.Object.Destroy(this.boxInitRootWidgets[i].gameObject);
		}
		this.boxInitRootWidgets.RemoveRange(index, this.boxInitRootWidgets.Count - index);
	}

	private void OnMouseDown(Vector3 mousePosition)
	{
		if (this.inputCancle != null && this.inputCancle())
		{
			return;
		}
		if (this.viewCamera == null || !this.viewCamera.enabled)
		{
			return;
		}
		if (this.curtain.activeSelf && !this.isTutorial)
		{
			return;
		}
		if (Scene.IsLocked && !this.isTutorial)
		{
			return;
		}
		if (this.isTutorial && this.curtain.activeSelf)
		{
			return;
		}
		if (this.currentRoot != null)
		{
			this.OnMouseUp(mousePosition);
		}
		this.lastFixedShadowPoint = null;
		Ray ray = this.viewCamera.ScreenPointToRay(UnityEngine.Input.mousePosition);
		RaycastHit[] array = Physics.RaycastAll(ray, 100f);
		float num = 99999f;
		foreach (RaycastHit raycastHit in array)
		{
			if (raycastHit.collider.gameObject.CompareTag("_box"))
			{
				float magnitude = (raycastHit.point - raycastHit.transform.position).magnitude;
				if (num > magnitude)
				{
					this.currentBox = raycastHit.collider.gameObject.GetComponent<BoxWidgetHandler>();
					num = magnitude;
				}
			}
			if (raycastHit.collider.gameObject.CompareTag("_setting"))
			{
				this.currentBox = null;
				return;
			}
		}
		if (this.currentBox == null)
		{
			return;
		}
		for (int j = 0; j < this.boxRootWidgets.Count; j++)
		{
			if (this.boxRootWidgets[j] == this.currentBox.transform.parent.GetComponent<BoxRootWidgetHandler>())
			{
				this.currentRoot = this.boxRootWidgets[j];
				this.currentShadowRoot = this.boxShadowRootWidgets[j];
				this.currentInitRoot = this.boxInitRootWidgets[j];
			}
		}
		if (!this.currentRoot.isPermitClick)
		{
			this.currentRoot = null;
			this.currentShadowRoot = null;
			this.currentInitRoot = null;
			return;
		}
		this.currentRoot.RemoveLastPosition(this.boardInfos);
		Vector3 vector = this.viewCamera.ScreenToWorldPoint(mousePosition);
		vector.z = 0f;
		this.clickObject.transform.position = vector;
		this.currentRoot.transform.parent = this.clickObject.transform;
		vector.z = -9f;
		this.clickObject.transform.position = vector;
		this.currentRoot.transform.localScale = Vector3.one;
		Vector3 b = this.GetBound(this.currentRoot).center - vector;
		b.y = this.GetBound(this.currentRoot).min.y - vector.y - 1f;
		this.currentRoot.transform.localPosition = this.currentRoot.transform.localPosition - b;
		this.currentRoot.SetOutline(true);
		this.SetColorBlock(false);
		this.StopTutorial();
		BMSoundHelper.Play("se_blockup", false, 1f);
		if (this.currentRoot != null && this.currentRoot.isSet)
		{
			this.currentShadowRoot.transform.position = this.currentInitRoot.transform.position;
			this.currentShadowRoot.gameObject.SetActive(false);
		}
	}

	private void OnMouseDrag(Vector3 mousePosition)
	{
		if (this.viewCamera == null || !this.viewCamera.enabled)
		{
			return;
		}
		if (this.curtain.activeSelf && !this.isTutorial)
		{
			return;
		}
		if (this.currentRoot == null)
		{
			return;
		}
		if (Scene.IsLocked && !this.isTutorial)
		{
			return;
		}
		if (this.isTutorial && this.curtain.activeSelf)
		{
			return;
		}
		Vector3 position = this.viewCamera.ScreenToWorldPoint(mousePosition);
		position.z = -9f;
		this.clickObject.transform.position = position;
		Vector3 position2 = base.transform.InverseTransformPoint(this.currentRoot.transform.position);
		Point point = BlocksCoordinate.coordinate.coordinate.WorldToPuzzle(position2);
		if (this.lastFixedShadowPoint != null)
		{
			Point point2 = this.lastFixedShadowPoint.Value - point;
			int num = 2;
			bool flag = Mathf.Abs(point2.x) > num || Mathf.Abs(point2.y) > num;
			if (flag)
			{
				this.currentShadowRoot.gameObject.SetActive(false);
				this.currentShadowRoot.transform.position = this.currentInitRoot.transform.position;
				this.lastFixedShadowPoint = null;
			}
		}
		if (this.currentRoot.IsValidPosition(this.boardInfos, point, true))
		{
			this.UpdateShadowPosition(point);
		}
	}

	private Bounds GetBound(BoxRootWidgetHandler go)
	{
		Bounds result = new Bounds(go.transform.position, Vector3.zero);
		for (int i = 0; i < go.boxWidgets.Count; i++)
		{
			result.Encapsulate(go.boxWidgets[i].GetComponent<Renderer>().bounds);
		}
		return result;
	}

	private void UpdateShadowPosition(Point currentRootPoint)
	{
		this.lastFixedShadowPoint = new Point?(currentRootPoint);
		this.currentShadowRoot.gameObject.SetActive(true);
		Vector3 localPosition = BlocksCoordinate.coordinate.coordinate.PuzzleToWorld(currentRootPoint);
		localPosition.z = -2f;
		this.currentShadowRoot.transform.localPosition = localPosition;
		this.currentShadowRoot.transform.localScale = Vector3.one;
	}

	private void OnMouseUp(Vector3 mousePosition)
	{
		if (this.viewCamera == null || !this.viewCamera.enabled)
		{
			return;
		}
		if (this.curtain.activeSelf && !this.isTutorial)
		{
			return;
		}
		if (this.currentRoot == null)
		{
			return;
		}
		if (Scene.IsLocked && !this.isTutorial)
		{
			return;
		}
		if (this.isTutorial && this.curtain.activeSelf)
		{
			return;
		}
		this.moveCount++;
		this.currentShadowRoot.gameObject.SetActive(false);
		this.currentShadowRoot.transform.parent = base.transform;
		this.currentRoot.transform.parent = base.transform;
		this.clickObject.transform.position = Vector3.zero;
		Vector3 position = base.transform.InverseTransformPoint(this.currentRoot.transform.position);
		Point point = BlocksCoordinate.coordinate.coordinate.WorldToPuzzle(position);
		if (this.lastFixedShadowPoint == null)
		{
			int index = this.boxRootWidgets.FindIndex((BoxRootWidgetHandler item) => item == this.currentRoot);
			this.OnMouseUpAnimation(this.boxInitRootWidgets[index], this.currentRoot, Vector3.one * BlocksCoordinate.coordinate.initCoordinate.size / BlocksCoordinate.coordinate.coordinate.size, 0.2f, null);
			BMSoundHelper.Play("se_blockwrong", false, 1f);
			this.currentRoot.isSet = false;
			if (this.onChangeBoard != null)
			{
				this.onChangeBoard();
			}
		}
		else
		{
			Vector3 localPosition = BlocksCoordinate.coordinate.coordinate.PuzzleToWorld(this.lastFixedShadowPoint.Value);
			localPosition.z = -2f;
			this.currentRoot.SetValidPosition(this.boardInfos, this.lastFixedShadowPoint.Value);
			this.currentRoot.transform.localPosition = localPosition;
			this.currentRoot.transform.localScale = Vector3.one;
			this.currentRoot.isSet = true;
			if (this.isTutorial)
			{
				this.StartTutorial();
			}
			BMSoundHelper.Play("se_blockdown", false, 1f);
			if (this.onChangeBoard != null)
			{
				this.onChangeBoard();
			}
			if (this.IsCleared() && this.onPuzzleClear != null)
			{
				this.onPuzzleClear(this.moveCount, this.boardInfos);
				this.StopHintAnimation();
			}
		}
		this.currentRoot.SetOutline(false);
		this.currentBox = null;
		this.currentRoot = null;
		if (this.onMouseCount != null)
		{
			this.onMouseCount(this.moveCount);
		}
	}

	private void OnMouseUpAnimation(BoxRootWidgetHandler handler, BoxRootWidgetHandler rootHandler, Vector3 scale, float time, Action CallBack = null)
	{
		Debugger.Assert(handler != null, "PuzzleCtrl handler != null");
		Debugger.Assert(rootHandler != null, "PuzzleCtrl rootHandler != null");
		Debugger.Assert(time >= 0f, "PuzzleCtrl time >= 0");
		HOTween.Complete(rootHandler.name);
		Vector3 localPosition = handler.transform.localPosition;
		rootHandler.isPermitClick = false;
		Sequence sequence = new Sequence(new SequenceParms().Id("OnMouseUpAnimation").Id(rootHandler.name).OnComplete(delegate()
		{
			rootHandler.isPermitClick = true;
			this.SetColorBlock(true);
			if (this.isTutorial)
			{
				this.StartTutorial();
			}
			if (CallBack != null)
			{
				CallBack();
			}
		}));
		sequence.Insert(0f, HOTween.To(rootHandler.transform, time, "localPosition", localPosition));
		sequence.Insert(0f, HOTween.To(rootHandler.transform, time, "localScale", scale));
		sequence.Play();
	}

	private void SetColorBlock(bool inclusionCurrentBlock = true)
	{
		for (int i = 0; i < this.boxRootWidgets.Count; i++)
		{
			for (int j = 0; j < this.boxRootWidgets[i].points.Count; j++)
			{
				Color32 c = this.boxRootWidgets[i].boxWidgets[j].sprite.color;
				c.a = byte.MaxValue;
				this.boxRootWidgets[i].boxWidgets[j].sprite.color = c;
			}
		}
		for (int k = 0; k < this.boxRootWidgets.Count; k++)
		{
			if (inclusionCurrentBlock || !(this.boxRootWidgets[k] == this.currentRoot))
			{
				for (int l = 0; l < this.boxRootWidgets.Count; l++)
				{
					if (inclusionCurrentBlock || !(this.boxRootWidgets[l] == this.currentRoot))
					{
						if (!this.boxRootWidgets[k].isSet && !this.boxRootWidgets[l].isSet)
						{
							if (k != l)
							{
								this.boxRootWidgets[k].SetOverlapColor(this.boxRootWidgets[l]);
							}
						}
					}
				}
			}
		}
	}

	public void UseReply()
	{
		bool flag = true;
		for (int i = 0; i < this.boardInfos.Count; i++)
		{
			if (this.boardInfos[i].index >= 0)
			{
				flag = false;
			}
			this.boardInfos[i].index = -1;
		}
		if (!flag)
		{
			BMSoundHelper.Play("se_blockreset", false, 1f);
		}
		else
		{
			BMSoundHelper.Play("se_btnclick", false, 1f);
		}
		int index = 0;
		for (int j = 0; j < this.boxRootWidgets.Count; j++)
		{
			this.boxShadowRootWidgets[j].gameObject.SetActive(false);
			this.OnMouseUpAnimation(this.boxInitRootWidgets[j], this.boxRootWidgets[j], Vector3.one * BlocksCoordinate.coordinate.initCoordinate.size / BlocksCoordinate.coordinate.coordinate.size, 0.2f, delegate
			{
				index++;
				if (this.boxRootWidgets.Count == index)
				{
					for (int k = 0; k < this.boxRootWidgets.Count; k++)
					{
						this.boxRootWidgets[k].SetPoints(this.initPoint, false);
						this.boxShadowRootWidgets[k].SetPoints(this.initPoint, false);
						this.boxInitRootWidgets[k].SetPoints(this.initPoint, false);
					}
				}
			});
		}
	}

	public bool UseHint()
	{
		int i;
		for (i = 0; i < this.boxHintRootWidgets.Count; i++)
		{
			if (!this.boxHintRootWidgets[i].usedHint)
			{
				bool flag = false;
				int num = this.boardInfos.FindIndex((BoardInfo item) => item.point == this.boxHintRootWidgets[i].points[0]);
				if (num < 0)
				{
					UnityEngine.Debug.Log("Not Valid");
					return false;
				}
				if (this.boardInfos[num].index < 0)
				{
					flag = true;
				}
				else if (this.boardInfos[num].index >= 0)
				{
					List<int> list = new List<int>();
					for (int l = 0; l < this.boxHintRootWidgets[i].points.Count; l++)
					{
						list.Add(BlocksCoordinate.coordinate.coordinate.PuzzleToIndex(this.boxHintRootWidgets[i].points[l]));
					}
					List<int> list2 = new List<int>();
					for (int j = 0; j < this.boardInfos.Count; j++)
					{
						if (this.boardInfos[num].index == this.boardInfos[j].index)
						{
							list2.Add(BlocksCoordinate.coordinate.coordinate.PuzzleToIndex(this.boardInfos[j].point));
						}
					}
					if (list.Count == list2.Count)
					{
						list.Sort((int a, int b) => a.CompareTo(b));
						list2.Sort((int a, int b) => a.CompareTo(b));
						for (int k = 0; k < list.Count; k++)
						{
							if (list[k] != list2[k])
							{
								flag = true;
								break;
							}
						}
					}
					else
					{
						flag = true;
					}
				}
				if (flag)
				{
					this.boxHintRootWidgets[i].gameObject.SetActive(true);
					this.boxHintRootWidgets[i].usedHint = true;
					this.StartHintAnimation(this.boxHintRootWidgets[i]);
					return true;
				}
			}
		}
		return false;
	}

	private void StartHintAnimation(BoxRootWidgetHandler handler)
	{
		Debugger.Assert(handler != null, "PuzzleCtrl handler != null");
		GameObject obj = new GameObject();
		obj.transform.parent = base.transform;
		obj.transform.position = Scene.GetRenderBound(handler.gameObject).center;
		handler.transform.parent = obj.transform;
		obj.transform.localScale = Vector3.one * 2f;
		obj.transform.eulerAngles = new Vector3(0f, 0f, 90f);
		Sequence sequence = new Sequence(new SequenceParms().OnComplete(delegate()
		{
			handler.transform.parent = this.transform;
			UnityEngine.Object.Destroy(obj);
		}));
		sequence.Insert(0f, HOTween.To(obj.transform, 0.5f, "localScale", Vector3.one));
		sequence.Insert(0f, HOTween.To(obj.transform, 0.5f, "eulerAngles", Vector3.zero));
		sequence.Play();
	}

	private bool IsCleared()
	{
		for (int i = 0; i < this.boardInfos.Count; i++)
		{
			if (this.boardInfos[i].index < 0)
			{
				return false;
			}
		}
		return true;
	}

	public void Solution(bool isShow)
	{
		for (int i = 0; i < this.boxHintRootWidgets.Count; i++)
		{
			this.boxHintRootWidgets[i].gameObject.SetActive(isShow);
		}
	}

	private void StopHintAnimation()
	{
		for (int i = 0; i < this.boxHintRootWidgets.Count; i++)
		{
			this.boxHintRootWidgets[i].gameObject.SetActive(false);
		}
	}

	public void ClearAnimation2()
	{
		BMSoundHelper.Play("se_blockani", false, 1f);
		for (int i = 0; i < this.boxRootWidgets.Count; i++)
		{
			this.boxShadowRootWidgets[i].gameObject.SetActive(false);
			for (int j = 0; j < this.boxRootWidgets[i].boxWidgets.Count; j++)
			{
				this.boxRootWidgets[i].boxWidgets[j].isClear = true;
			}
		}
		for (int k = 0; k < this.hinderWidgets.Count; k++)
		{
			this.hinderWidgets[k].gameObject.transform.localPosition = this.hinderWidgets[k].gameObject.transform.localPosition + Vector3.forward * 1f;
		}
	}

	public float ClearAnimation()
	{
		BMSoundHelper.Play("clear_light", false, 1f);
		List<BoxWidgetHandler> list = new List<BoxWidgetHandler>();
		float num = 0f;
		for (int i = 0; i < this.boxRootWidgets.Count; i++)
		{
			if (this.boxRootWidgets[i].isSet)
			{
				for (int j = 0; j < this.boxRootWidgets[i].boxWidgets.Count; j++)
				{
					list.Add(this.boxRootWidgets[i].boxWidgets[j]);
				}
			}
		}
		for (int k = 0; k < list.Count; k++)
		{
			Vector3 position = base.transform.InverseTransformPoint(list[k].transform.position);
			Point point = BlocksCoordinate.coordinate.coordinate.WorldToPuzzle(position);
			float num2 = ((float)point.x + (float)point.y) / 20f;
			if (num < num2)
			{
				num = num2;
			}
			int num3 = this.boardInfos.FindIndex((BoardInfo item) => item.point == point);
			if (num3 >= 0)
			{
				list[k].changeColor = this.boardInfos[num3].changeColorIndex;
			}
			base.StartCoroutine(this.CoClearAnimation(list[k], num2));
		}
		return num + 0.7f;
	}

	private IEnumerator CoClearAnimation(BoxWidgetHandler block, float time)
	{
		yield return new WaitForSeconds(time);
		block.ClearAnimation();
		yield break;
	}

	public void StartTutorial()
	{
		HOTween.Kill("StartFingerAnimation");
		this.finger.gameObject.SetActive(false);
		Vector3 position = default(Vector3);
		Vector3 vector = default(Vector3);
		bool flag = false;
		int i;
		for (i = 0; i < this.boxHintRootWidgets.Count; i++)
		{
			bool flag2 = true;
			int num = this.boardInfos.FindIndex((BoardInfo item) => item.point == this.boxHintRootWidgets[i].points[0]);
			if (num < 0)
			{
				flag2 = false;
			}
			if (this.boardInfos[num].index < 0)
			{
				flag2 = false;
			}
			else if (this.boardInfos[num].index >= 0)
			{
				List<int> list = new List<int>();
				for (int l = 0; l < this.boxHintRootWidgets[i].points.Count; l++)
				{
					list.Add(BlocksCoordinate.coordinate.coordinate.PuzzleToIndex(this.boxHintRootWidgets[i].points[l]));
				}
				List<int> list2 = new List<int>();
				for (int j = 0; j < this.boardInfos.Count; j++)
				{
					if (this.boardInfos[num].index == this.boardInfos[j].index)
					{
						list2.Add(BlocksCoordinate.coordinate.coordinate.PuzzleToIndex(this.boardInfos[j].point));
					}
				}
				if (list.Count == list2.Count)
				{
					list.Sort((int a, int b) => a.CompareTo(b));
					list2.Sort((int a, int b) => a.CompareTo(b));
					for (int k = 0; k < list.Count; k++)
					{
						if (list[k] != list2[k])
						{
							flag2 = false;
						}
					}
				}
				else
				{
					flag2 = false;
				}
			}
			if (!flag2)
			{
				this.boxHintRootWidgets[i].gameObject.SetActive(true);
				this.boxHintRootWidgets[i].usedHint = true;
				position = this.boxRootWidgets[i].gameObject.transform.position;
				position.z = -50f;
				vector = this.boxHintRootWidgets[i].gameObject.transform.position;
				vector.z = -50f;
				flag = true;
				break;
			}
		}
		if (flag)
		{
			this.finger.transform.position = position;
			this.finger.gameObject.SetActive(true);
			Sequence sequence = new Sequence(new SequenceParms().Id("StartFingerAnimation").OnComplete(delegate()
			{
				this.StartTutorial();
			}));
			sequence.Insert(0.2f, HOTween.To(this.finger.transform, 1f, new TweenParms().Prop("position", vector).Ease(EaseType.Linear)));
			sequence.AppendInterval(0.5f);
			sequence.Play();
		}
	}

	public void StopTutorial()
	{
		this.finger.gameObject.SetActive(false);
		HOTween.Kill("StartFingerAnimation");
	}

	public void RemoveBoard()
	{
		this.ClearBoxRootWidget(0);
		this.ClearBoxHintRootWidget(0);
		this.ClearBoxShadowRootWidget(0);
		this.ClearBoxInitRootWidget(0);
		this.ClearHinderWidget(0);
		this.ClearInitBoardWidget(0);
		this.ClearBoardWidget(0);
	}

	public PuzzleCtrl.OnInputCancle inputCancle;

	public Action<int> onMouseCount;

	public Action<int, List<BoardInfo>> onPuzzleClear;

	public Camera viewCamera;

	public GameObject boardBg;

	public GameObject clickObject;

	public GameObject initPoint;

	public bool isEdit;

	public GameObject topPosition;

	public GameObject bottomPosition;

	public GameObject finger;

	public GameObject curtain;

	public Action onChangeBoard;

	private float topY;

	private float bottomY;

	private bool isTutorial;

	private CheckVaildInitPosition vaildInitPosition = new CheckVaildInitPosition();

	private List<BoardWidgetHandler> boardWidgets = new List<BoardWidgetHandler>();

	private List<BoardWidgetHandler> initBoardWidgets = new List<BoardWidgetHandler>();

	private List<HinderWidgetHandler> hinderWidgets = new List<HinderWidgetHandler>();

	private List<BoxRootWidgetHandler> boxRootWidgets = new List<BoxRootWidgetHandler>();

	private List<BoxRootWidgetHandler> boxHintRootWidgets = new List<BoxRootWidgetHandler>();

	private List<BoxRootWidgetHandler> boxShadowRootWidgets = new List<BoxRootWidgetHandler>();

	private List<BoxRootWidgetHandler> boxInitRootWidgets = new List<BoxRootWidgetHandler>();

	private List<BoardInfo> boardInfos = new List<BoardInfo>();

	private List<BoardInfo> initInfos = new List<BoardInfo>();

	private BoxWidgetHandler currentBox;

	private BoxRootWidgetHandler currentRoot;

	private BoxRootWidgetHandler currentShadowRoot;

	private BoxRootWidgetHandler currentInitRoot;

	private Level currentlevel;

	private int moveCount;

	private Vector3 downPos = Vector3.zero;

	private Point? lastFixedShadowPoint;

	public delegate bool OnInputCancle();
}
